﻿using Model;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Tool;

namespace 固高控制
{
    public partial class Form1 : Form
    {
        public Direction directionState;

        GuGao guGao = null;

        public Form1()
        {
            InitializeComponent();
            //实例化
            guGao = new GuGao();

            #region Jog运动按钮绑定
            //this.btn_Front:前
            this.btn_Front.MouseDown += (sender, e) =>
            {
                Console.WriteLine("鼠标弹起");
                guGao.Jop_Move(2, MovementDirection.front);
            };
            this.btn_Front.MouseUp += (sender, e) =>
            {
                guGao.Jop_Stop(2);
            };

            //this.button14:后
            this.btn_After.MouseDown += (sender, e) =>
            {
                guGao.Jop_Move(2, MovementDirection.after);
            };
            this.btn_After.MouseUp += (sender, e) =>
            {
                guGao.Jop_Stop(2);
            };
            //this.button13:左
            this.btn_Left.MouseDown += (sender, e) =>
            {
                guGao.Jop_Move(1, MovementDirection.left);
            };
            this.btn_Left.MouseUp += (sender, e) =>
            {
                guGao.Jop_Stop(1);
            };
            //this.button15:右
            this.btn_Right.MouseDown += (sender, e) =>
            {
                guGao.Jop_Move(1, MovementDirection.right);
            };
            this.btn_Right.MouseUp += (sender, e) =>
            {
                guGao.Jop_Stop(1);
            };
            //this.button16:升
            this.btn_Rise.MouseDown += (sender, e) =>
            {
                guGao.Jop_Move(4, MovementDirection.rise);
            };
            this.btn_Rise.MouseUp += (sender, e) =>
            {
                guGao.Jop_Stop(4);
            };
            //this.button17:降
            this.btn_Drop.MouseDown += (sender, e) =>
            {
                guGao.Jop_Move(4, MovementDirection.drop);
            };
            this.btn_Drop.MouseUp += (sender, e) =>
            {
                guGao.Jop_Stop(4);
            };
            //重置
            this.btn_JopReset.Click += (sender, e) =>
            {
                //P2P重置
                guGao.P2P_Reset();
            };
            #endregion

            #region P2P运动按钮绑定
            //P2P:X轴
            this.btn_XRun.Click += (sender, e) =>
            {
                //获取要移动的位置，此时是坐标轴的位置
                int MovePointX = int.Parse(this.txb_P2P_X.Text);
                //转换成为X轴移动的量
                int posX = -MovePointX * 250;
                //驱动轴开始移动
                guGao.P2P_Move(1, posX);
            };
            //P2P:Y轴
            this.btn_YRun.Click += (sender, e) =>
            {
                //获取要移动的位置，此时是坐标轴的位置
                int MovePointY = int.Parse(this.txb_P2P_Y.Text);
                //转换成为X轴移动的量
                int posY = MovePointY * 250;
                //驱动轴开始移动
                guGao.P2P_Move(2, posY);
            };
            //P2P:Z轴
            this.btn_ZRun.Click += (sender, e) =>
            {

                guGao.P2P_Move(4, int.Parse(this.txb_P2P_Z.Text));
            };

            //P2P:重置
            this.btn_StopP2P.Click += (sender, e) =>
            {
                guGao.P2P_Reset();
            };

            #endregion


            //设置获取界面Jop参数
            guGao.changeJopParams = GetJopParams;
            //设置获取界面P2P参数
            guGao.delP2PParams = GetP2pParams;

            //设置界面相应限位
            guGao.UpdatePositiveLimit = SetPositive;
            guGao.UpdateNegativeLimit = SetNegative;


            //绑定定时器,固高的定时器
            this.timer1.Tick += guGao.TimeTick;

            //绑定轴的更新
            guGao.UpdateX += t =>
            {
                this.X.Text = t.ToString();
            };
            guGao.UpdateY += t =>
            {
                this.Y.Text = t.ToString();
            };
            guGao.UpdateZ += t => this.Z.Text = t.ToString();
        }

        /// <summary>
        /// 获取Jop运动参数
        /// </summary>
        /// <param name="vel"></param>
        /// <param name="acc"></param>
        /// <param name="dec"></param>

        private void GetJopParams(ref double vel, ref double acc, ref double dec)
        {
            vel = Convert.ToDouble(this.txb_JopVel.Text);
            acc = Convert.ToDouble(this.txb_JopAcc.Text);
            dec = Convert.ToDouble(this.txb_JopDec.Text);
        }


        /// <summary>
        /// 获取Jog运动参数
        /// </summary>
        /// <param name="vel"></param>
        /// <param name="acc"></param>
        /// <param name="dec"></param>
        /// <param name="smoothTime"></param>
        private void GetP2pParams(ref double vel, ref double acc, ref double dec, ref short smoothTime)
        {
            vel = Convert.ToDouble(this.txb_P2PVel.Text);
            acc = Convert.ToDouble(this.txb_P2PAcc.Text);
            dec = Convert.ToDouble(this.txb_P2PDec.Text);
            smoothTime = short.Parse(this.txb_P2PSmooth.Text);
        }

        /// <summary>
        /// 打开板卡
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_Load(object sender, EventArgs e)
        {
            //打开板卡
            guGao.GuGaoOpen(1);
        }

        /// <summary>
        /// 原点复归
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_InitAll_Click(object sender, EventArgs e)
        {
            guGao.Jop_Reset();//JOP重置

            Task X = Task.Run(() =>
            {
                //X轴按下直到碰到限位开关为止
                guGao.Jop_Move(1, MovementDirection.left);
                //检测当遇到限位开关停止
                while (true)
                {
                    if (this.XPositiveLimite.BackColor == Color.Red)
                    {
                        guGao.Jop_Stop(1);
                        break;
                    }
                    Thread.Sleep(3);
                }
            });

            Task Y = Task.Run(() =>
            {
                //X轴按下直到碰到限位开关为止
                guGao.Jop_Move(2, MovementDirection.left);
                //检测当遇到限位开关停止
                while (true)
                {
                    if (this.YPositiveLimite.BackColor == Color.Red)
                    {
                        guGao.Jop_Stop(2);
                        break;
                    }
                    Thread.Sleep(3);
                }
            });

            Task Z = Task.Run(() =>
            {
                //X轴按下直到碰到限位开关为止
                guGao.Jop_Move(4, MovementDirection.left);
                //检测当遇到限位开关停止
                while (true)
                {
                    if (this.ZPositiveLimite.BackColor == Color.Red)
                    {
                        guGao.Jop_Stop(4);
                        break;
                    }
                    Thread.Sleep(3);
                }
            });

            Task.WhenAll(X, Y, Z).ContinueWith(t =>
            {
                //重置为P2P运动
                guGao.P2P_Reset();
                //设置前往指定的目标
                guGao.P2P_Move(1, int.Parse(this.txb_Init_X.Text));
                guGao.P2P_Move(2, int.Parse(this.txb_Init_Y.Text));
                guGao.P2P_Move(4, int.Parse(this.txb_Init_Z.Text));

                while (true)
                {
                    if (this.X.Text == this.txb_Init_X.Text && this.Y.Text == this.txb_Init_Y.Text && this.Z.Text == this.txb_Init_Z.Text)
                    {
                        break;
                    }
                    Thread.Sleep(2);
                }

                //P2P重置
                guGao.P2P_Reset();

            });
        }


        /// <summary>
        /// 设置正限位颜色
        /// </summary>
        /// <param name="lGpiValue"></param>
        public void SetPositive(int lGpiValue)
        {
            //X
            this.XPositiveLimite.BackColor = (lGpiValue & 1) == 0 ? Color.Red : Color.SeaGreen;
            //Y
            this.YPositiveLimite.BackColor = (lGpiValue & 2) == 0 ? Color.Red : Color.SeaGreen;
            //Z
            this.ZPositiveLimite.BackColor = (lGpiValue & 4) == 0 ? Color.Red : Color.SeaGreen;
        }
        /// <summary>
        /// 设置负限位
        /// </summary>
        /// <param name="lGpiValue"></param>
        public void SetNegative(int lGpiValue)
        {
            //X
            this.XNegtiveLimite.BackColor = (lGpiValue & 1) == 0 ? Color.Red : Color.SeaGreen;
            //Y
            this.YNegtiveLimite.BackColor = (lGpiValue & 2) == 0 ? Color.Red : Color.SeaGreen;
            //Z
            this.ZNegtiveLimite.BackColor = (lGpiValue & 4) == 0 ? Color.Red : Color.SeaGreen;

        }

        /// <summary>
        /// 生成9点
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btn_CreateNinePoints_Click(object sender, EventArgs e)
        {
            // 清空现有节点
            this.coordinateAxisControl2.nodes.Clear();

            // 定义坐标点的间距
            int spacing = 80;  // 相邻点之间的距离

            // 创建9个标定点，按照3x3网格排列
            NodeClass node1 = new NodeClass("1号", -spacing, spacing, Color.Red, this.coordinateAxisControl2.Invalidate);
            NodeClass node2 = new NodeClass("2号", 0, spacing, Color.Red, this.coordinateAxisControl2.Invalidate);
            NodeClass node3 = new NodeClass("3号", spacing, spacing, Color.Red, this.coordinateAxisControl2.Invalidate);

            NodeClass node4 = new NodeClass("4号", -spacing, 0, Color.Red, this.coordinateAxisControl2.Invalidate);
            NodeClass node5 = new NodeClass("5号", 0, 0, Color.Red, this.coordinateAxisControl2.Invalidate);
            NodeClass node6 = new NodeClass("6号", spacing, 0, Color.Red, this.coordinateAxisControl2.Invalidate);

            NodeClass node7 = new NodeClass("7号", -spacing, -spacing, Color.Red, this.coordinateAxisControl2.Invalidate);
            NodeClass node8 = new NodeClass("8号", 0, -spacing, Color.Red, this.coordinateAxisControl2.Invalidate);
            NodeClass node9 = new NodeClass("9号", spacing, -spacing, Color.Red, this.coordinateAxisControl2.Invalidate);

            // 添加所有节点
            this.coordinateAxisControl2.nodes.AddRange(new[] {
                                                                                node1, node2, node3,
                                                                                node4, node5, node6,
                                                                                node7, node8, node9
                                                                        });

            // 强制重绘
            this.coordinateAxisControl2.Invalidate();

            //绑定ListBox显示
            this.listBox1.DataSource = this.coordinateAxisControl2.nodes;
        }

        private void btn_CreateNinePath_Click(object sender, EventArgs e)
        {
            // 检查是否有足够的节点
            if (coordinateAxisControl2.nodes.Count < 2)
                return;

            // 创建轨迹起点（使用第一个节点的坐标）
            var firstNode = coordinateAxisControl2.nodes[0];
            // 需要将节点坐标转换为屏幕坐标
            Point startPoint = new Point(
                firstNode.X + coordinateAxisControl2.Width / 2,
                coordinateAxisControl2.Height / 2 - firstNode.Y
            );

            // 创建轨迹对象
            CustomPathShape pathShape = new CustomPathShape("九点轨迹点坐标", startPoint, Color.FromArgb(45, 46, 54));


            for (int i = 0; i < coordinateAxisControl2.nodes.Count; i++)
            {
                //遍历坐标点，然后转换成对应的像素点坐标添加进入
                Point point = new Point();
                point.X = coordinateAxisControl2.Width / 2 + coordinateAxisControl2.nodes[i].X;
                point.Y = coordinateAxisControl2.Height / 2 - coordinateAxisControl2.nodes[i].Y;

                pathShape.Update(new Point(point.X, point.Y));
            }
            // 将生成的轨迹添加到控件中
            coordinateAxisControl2.AddShape(pathShape);

            // 刷新显示
            coordinateAxisControl2.Invalidate();
        }

        private void btn_AddNinePoints_Path_Click(object sender, EventArgs e)
        {
            // 清空现有节点
            this.coordinateAxisControl2.nodes.Clear();

            // 定义坐标点的间距
            int spacing = 80;  // 相邻点之间的距离

            // 创建9个标定点，按照3x3网格排列
            NodeClass node1 = new NodeClass("1号", -spacing, spacing, Color.Red, this.coordinateAxisControl2.Invalidate);
            NodeClass node2 = new NodeClass("2号", 0, spacing, Color.Red, this.coordinateAxisControl2.Invalidate);
            NodeClass node3 = new NodeClass("3号", spacing, spacing, Color.Red, this.coordinateAxisControl2.Invalidate);

            NodeClass node4 = new NodeClass("4号", -spacing, 0, Color.Red, this.coordinateAxisControl2.Invalidate);
            NodeClass node5 = new NodeClass("5号", 0, 0, Color.Red, this.coordinateAxisControl2.Invalidate);
            NodeClass node6 = new NodeClass("6号", spacing, 0, Color.Red, this.coordinateAxisControl2.Invalidate);

            NodeClass node7 = new NodeClass("7号", -spacing, -spacing, Color.Red, this.coordinateAxisControl2.Invalidate);
            NodeClass node8 = new NodeClass("8号", 0, -spacing, Color.Red, this.coordinateAxisControl2.Invalidate);
            NodeClass node9 = new NodeClass("9号", spacing, -spacing, Color.Red, this.coordinateAxisControl2.Invalidate);

            // 添加所有节点
            this.coordinateAxisControl2.nodes.AddRange(new[] {
                                                                                node1, node2, node3,
                                                                                node4, node5, node6,
                                                                                node7, node8, node9
                                                                        });

            // 强制重绘
            this.coordinateAxisControl2.Invalidate();

            //绑定ListBox显示
            this.listBox1.DataSource = this.coordinateAxisControl2.nodes;
        }

        private void btn_CreatNinePointsPath_Path_Click(object sender, EventArgs e)
        {
            // 检查是否有足够的节点
            if (coordinateAxisControl2.nodes.Count < 2)
                return;

            // 创建轨迹起点（使用第一个节点的坐标）
            var firstNode = coordinateAxisControl2.nodes[0];
            // 需要将节点坐标转换为屏幕坐标
            Point startPoint = new Point(
                firstNode.X + coordinateAxisControl2.Width / 2,
                coordinateAxisControl2.Height / 2 - firstNode.Y
            );

            // 创建轨迹对象
            CustomPathShape pathShape = new CustomPathShape("九点轨迹点坐标", startPoint, Color.FromArgb(45, 46, 54));

            // 遍历所有节点，生成插补轨迹
            for (int i = 0; i < coordinateAxisControl2.nodes.Count; i++)
            {
                var currentNode = coordinateAxisControl2.nodes[i];
                //var nextNode = coordinateAxisControl2.nodes[i + 1];

                // 将节点坐标转换为屏幕坐标
                Point currentPoint = new Point(
                    currentNode.X + coordinateAxisControl2.Width / 2,
                    coordinateAxisControl2.Height / 2 - currentNode.Y
                );

                // 将生成的轨迹添加到控件中
                coordinateAxisControl2.AddShape(pathShape);

                pathShape.Update(currentPoint);
            }

            // 将生成的轨迹添加到控件中
            coordinateAxisControl2.AddShape(pathShape);

            // 刷新显示
            coordinateAxisControl2.Invalidate();
        }

        private void btn_Run_Path_Click(object sender, EventArgs e)
        {
            coordinateAxisControl2.StartAnimation();
        }

        private void btn_RunNinePoints_Click(object sender, EventArgs e)
        {
            //使用直线插补，先插入坐标数据
            List<Point> points = this.coordinateAxisControl2.nodes.Select(t => new Point() { X = t.X * 250 * -1, Y = t.Y * 250 }).ToList();

            //建立插补坐标系,会以当前的坐标为原点，注意清零操作98
            guGao.Establish_coordinate_system();
            //将坐标录入进入然后运行
            guGao.Linear_Difference_Compensation_Move(points);

        }
    }
}
